home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Grand Slam 3
/
Grand Slam 3.iso
/
023
/
dgtrekr3.arj
/
DRV_SRC.EXE
/
MYMIDI.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-12-27
|
7KB
|
298 lines
.MODEL LARGE,C
.386
include driver.inc
include middrivr.inc
assume cs:@code, ds:nothing, ss:nothing ; assume CS as default segment
.CODE
;-----------------------------------------
; Header
;-----------------------------------------
ORG 0
db "MIDIDRV",EOF
dw offset dispatcher
dw offset infoString
;-----------------------------------------
; Data
;-----------------------------------------
infoString db "generic MIDI driver for no-MIDI",0
oldISR dd ? ; old interrupt service routine
irq db 5 ; interrupt request for MIDI card
irqMask db ? ; interrupt mask register
irqMask2 db ? ; cascaded interrupt mask register
port dw 300h ; I/O address of MIDI card
clientFunction dd 0 ; callback function for MIDI messages
dataNeeded dw 0 ; data bytes needed for current cmd
dataMissing dw 0 ; data bytes missing for complete msg
midiCmd label byte ; first byte of buffer is the command
msgBuffer db 16 dup (?)
bufferOffset dw 1 ; buffer offset for next data byte
;-----------------------------------------
; Code
;-----------------------------------------
dispatcher proc
cmp bx,MAXFN
jnb error
shl bx,1
jmp function[bx]
error:
mov ax,ERR_BadFunction
ret
function label word
dw offset drvInit
dw offset drvSetClient
dw offset drvWrite
dw offset drvTerminate
MAXFN equ ($-offset function)/size word
dispatcher endp
;--------------------------------------------------
drvInit proc
LOCAL buffer[5] :DWORD, tmpMask :BYTE
xor ax,ax
mov es,ax
; add code here to locate irq
movzx bx,irq
cmp bx,8
jb @F
add bx,70h-8-8
@@: add bx,8
shl bx,2
mov eax,es:[bx]
mov oldISR,eax
; check if there is already a driver installed
push eax
pop ax
pop fs
mov ax,ERR_Busy
cmp dword ptr fs:[0004h],"VRD"+EOF shl 24 ; reverse "DRV",EOF
je done
; install new handler
mov es:[bx+0],offset midiHandler
mov es:[bx+2],cs
enableIRQ:
mov cl,irq
mov dx,21h
cmp cl,8
jb loIrq
hiIrq:
mov dx,0A1h ; address of 2nd int ctrl
in al,21h ; enable cascaded irq 2
mov irqMask2,al
and al,NOT 04h
out 21h,al
sub cl,8
loIrq:
mov ah,0FEh
rol ah,cl
in al,21h ; read mask
mov irqMask,al ; save mask
and al,ah ; clear the irq mask for MIDI irq
out 21h,al ; write mask
mov ax,ERR_Ok
done:
cmp ax,1
cmc
ret
drvInit endp
;=======================================
drvSetClient proc
mov clientFunction,eax
mov midiCmd,0 ; current midi command unknown
or eax,eax
jz stopMidi
startMIDI:
; add code here to enable MIDI receive
jmp done
stopMidi:
; add code here to disable MIDI receive
done:
mov ax,ERR_Ok
clc
ret
drvSetClient endp
;=======================================
drvWrite proc,
buffer :ptr byte, bufferLen :word
les bx,buffer
mov cx,bufferLen
jcxz done
nextByte:
mov al,es:[bx]
; add code here to make a MIDI out
inc bx
loop nextByte
done:
ret
drvWrite endp
;========================================
drvTerminate proc uses es
cmp irq,0 ; if irq wasn't found, then don't uninstall it
je exit
cmp clientFunction,0 ; stop MIDI reception
je notRunning
mov eax,0
call drvSetClient
notRunning:
movzx bx,irq
mov dx,21h ; restore old interrupt masks
cmp bx,8
jb loIrq
hiIrq:
mov al,irqMask2
out 21h,al
mov dx,0A1h
add bx,70h-8-8
loIrq:
mov al,irqMask
out dx,al
xor ax,ax ; restore old interrupt service routine
mov es,ax
add bx,8
shl bx,2
mov eax,oldISR
mov es:[bx],eax
exit:
clc
mov ax,ERR_Ok
ret
drvTerminate endp
;.----------------------------------.
;| internal functions |
;`----------------------------------'
;=======================================
midiHandler proc far
push ax
push bx
push dx
sti
; add code here to make a MIDI in
; in al,MIDIPORT
; if there is no client, drop the message
cmp clientFunction,0
je exit
test al,80h ; is it a MIDI command (bit 7=1) ?
jnz manageMidiCommand
cmp midiCmd,0 ; drop data byte if command is unknown
je exit
mov bx,bufferOffset ; store the data byte in the message buffer
mov msgBuffer[bx],al
inc bufferOffset
dec dataMissing
js exit ; more data than expected, drop it
jmp execCommand ; execute if all data was read
manageMidiCommand:
cmp al,0F8h ; drop clock message
je exit
cmp al,0FEh ; drop active sensing message
je exit
; get the number of data bytes for the command
mov dx,2
cmp al,0C0h
jb gotArgNum ; 8x,9x,Ax,Bx
mov dx,1
cmp al,0E0h ; Cx,Dx
jb gotArgNum
mov dx,2
cmp al,0F0h
jb gotArgNum ; Ex
mov dx,0FFFFh ; (actually drop all data)
je gotArgNum ; F0 (system exclusive)
mov dx,2
cmp al,0F2h
jbe gotArgNum
mov dx,1
cmp al,0F3h
je gotArgNum
mov dx,0
gotArgNum:
mov dataNeeded,dx
mov dataMissing,dx
mov bufferOffset,1
mov midiCmd,al
execCommand:
cmp dataMissing,0
jne exit ; still data missing, so nothing to do
mov dx,dataNeeded ; reinitialize command
mov dataMissing,dx
pushad ; save registers
push es
push cs
push offset msgBuffer ; call the C client function
call clientFunction
add sp,4
pop es
popad ; restore registers
exit:
mov al,EOI
cmp irq,8
jb @F
out 0A0h,al
@@: out 20h,al
pop dx
pop bx
pop ax
iret
midiHandler endp
END